﻿/*
   Author: Tomer Paz
   games.com
   2009
*/

/* the Players Status viewer */

package monopoly.views {
	
	import flash.display.Sprite;
	import flash.display.Stage;
	import fl.controls.Label;
	import flash.display.BlendMode;
	import fl.events.*;
	import flash.events.*;
	import fl.events.ComponentEvent;
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	import flash.text.TextFieldAutoSize;

	import monopoly.Player.Player;
	import monopoly.Player.PlayersCollection;
	import monopoly.IFS.Collections.ICollection;
	import monopoly.IFS.iterators.IIterator;
	import monopoly.IFS.GLOBALS;
	import monopoly.views.PlayerStatusBox;
	import monopoly.Localization.*;

	
	public class PlayersStatusView extends Sprite
		{
		protected var _players:PlayersCollection;
		protected var _playersLabelMap:Dictionary = new Dictionary( );
		protected var _lastPlayerY:Number = 0;
		protected var _diesLabel:Label;
		protected var _myStrings:ILocalLanguage = LocalLanguage.getInstance();
		protected var _diesLabelStr:String = _myStrings.StatusDiesRes;
		protected var _rootStage:Stage;
		
		protected var _DefaultWidth:Number = 140;
		protected var _DefaultHeight:Number= 210;
		
		protected static const ACTIVE_COLOR:Number		= 0x0000FF;
		protected static const INACTIVE_COLOR:Number	= 0xFF0000;
		protected static const RESIGN_COLOR:Number		= 0xFFFFFF;

		
		public function PlayersStatusView(Players:PlayersCollection, boardWidth:Number, boardHeight:Number, rootStage:Stage)
			{
			_rootStage = rootStage;
			
			setupStatusArea(boardWidth, boardHeight);
			//setupDiesLabel();
			
			_players = Players;
			
			_players.addEventListener(Event.ADDED, onAddPlayer);
			_players.addEventListener(Event.REMOVED, onRemovedPlayer);
			
			addPlayers();
			}

		public function setupStatusArea(boardWidth:Number, boardHeight:Number):void
			{
			// due to fucking Flash bug! this settings works only from caller class (GameController) meanwhile...
			this.height = _DefaultHeight;
			this.width  = _DefaultWidth;
			
			// position ourselves
			//this.x = boardWidth - this.width;
			//this.y = 5;

			this.graphics.beginFill(GLOBALS.DEFAULT_BG_COLOR);
			this.graphics.drawRect(0, 0, width, height);	
			this.graphics.endFill();
			
			this.blendMode	= BlendMode.LAYER;
			this.alpha		= 1;
			}
			
		public function set diesResult(result:String):void
			{
			_diesLabel.text = _diesLabelStr + result;
			_diesLabel.drawNow();
			}
		
		public function change_status(player:Player):void
			{
			/* first reset all players */
			
			for (var p:Object in _playersLabelMap)
				{
				if (_playersLabelMap[p][1].Status)
					{
					if (p != player)
						{
						// if player has Resigned, skip it!
						if (false == p.isActive)
							continue;
							
						_playersLabelMap[p][1].change_status();		// Negate any Active player if found
						
						with ((_playersLabelMap[p][0].parent as Sprite).graphics)
							{
							lineStyle(0, INACTIVE_COLOR, 1, false, "normal", p.Name);
							beginFill(INACTIVE_COLOR, 0.9);
							drawCircle(_DefaultWidth * 0.85, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.5, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.3);
							endFill();
							}
						}
					else
						return;		// if this player is already active shall remain so...
					}
				}
				
			_playersLabelMap [ player ][1].change_status();
			
			/* update the psprite parent with Active circle color */			
			
			with ((_playersLabelMap [ player ][0].parent as Sprite).graphics)
				{
				lineStyle(0, ACTIVE_COLOR, 1, false, "normal", player.Name);
				beginFill(ACTIVE_COLOR, 0.9);
	         	drawCircle(_DefaultWidth * 0.85, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.5, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.3);
				endFill();
				}
			}
		/*
		public override function set width(value:Number):void
			{
			super.width = value;
			
			for (var key:Object in _playersLabelMap)
				{
				_playersLabelMap [ key ][1].width = value;

				if (GLOBALS.DEBUG & GLOBALS.DEBUG_VIEW)
					trace("[PlayerStatusView][width] PlayerStatus.width = " + _playersLabelMap [ key ][1].width + " and y = " + _playersLabelMap [ key ][1].y);
				}
			}
		*/
		/* Protected area */
		
		protected function setupDiesLabel():void
			{
			_diesLabel = new Label();
			_diesLabel.move(5, _lastPlayerY + 5);
			_diesLabel.text = _diesLabelStr;
			_diesLabel.autoSize = TextFieldAutoSize.LEFT;
			
			addChild(_diesLabel);
			}
		
		protected function addPlayers():void
			{
			/* iterate over collection and add players rows to view */
			
			var playerIterator:IIterator = _players.iterator();
			var player:Player;
			
			for (var i:uint = 0; playerIterator.hasNext() && (player = Player(playerIterator.next())); i++)
				{
				addPlayerRow(player);
				}
				
			/* add empty fields */
			
			if (i < GLOBALS.MAX_NUM_PLAYERS)
				{
				for (i = i+1; i <= GLOBALS.MAX_NUM_PLAYERS; i++)
					{
					add_empty_viewer(i);
					}
				}
				
			/* now it is time to add dies label */
			
			setupDiesLabel();
			}
		
		protected function addPlayerRow(player:Player):void
			{
			if (null != _playersLabelMap[player])
				return;

			_playersLabelMap[player] = add_player_viewers(player);
			
			player.addEventListener(Event.RESIZE, onCashUpdate);
			}
			
		protected function removePlayerRow(player:Player):void
			{
			(_playersLabelMap[player][0] as Label).text = _myStrings.StatusHasQuit(player.Name);
			(_playersLabelMap[player][1] as PlayerStatusBox).undraw_statusBox();
			with ((_playersLabelMap[player][0].parent as Sprite).graphics)
				{
				lineStyle(0, RESIGN_COLOR, 1, false, "normal", player.Name);
				beginFill(RESIGN_COLOR, 0.9);
				drawCircle(_DefaultWidth * 0.85, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.5, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.3);
				endFill();
				}
			draw();
			}
		
		protected function add_player_viewers(player:Player):Array
			{
			var plabel:Label = new Label();
			var labelStr:String = player.Name + "." + _myStrings.StatusCash + player.Cash;
			plabel.autoSize = TextFieldAutoSize.LEFT;
			
			plabel.text = labelStr;
			
			/* create a wrapping sprite object + status box */
			
			var psprite:Sprite = new Sprite();
			
			with (psprite)
				{
				x		= 1;
				y		= _lastPlayerY + 2;
				
				if (GLOBALS.DEBUG & GLOBALS.DEBUG_VIEW)
					trace("[PlayerStatusView] [psprite] x = " + psprite.x + ", y = " + psprite.y);
			
				with (graphics) 
					{
					lineStyle(0, GLOBALS.PCOLORS[player.ID - 1], 1, false, "normal", player.Name);
					beginFill(GLOBALS.PCOLORS[player.ID - 1], 0.7);
		         	drawRoundRect(0, 0, _DefaultWidth - 1, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)), 5, 5);
					endFill();
					
					/* create a circle flashing status light */

					lineStyle(0, INACTIVE_COLOR, 1, false, "normal", player.Name);
					beginFill(INACTIVE_COLOR, 0.9);
		         	drawCircle(_DefaultWidth * 0.85, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.5, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)) * 0.3);
					endFill();
					}
				blendMode = BlendMode.LAYER;
			
				addChild(plabel);
				}
				
			
			var pstatusBox:PlayerStatusBox = new PlayerStatusBox(player);
			pstatusBox.addEventListener(Event.COMPLETE, onStatusBoxComplete);
			pstatusBox.load();
			pstatusBox.y = _lastPlayerY;
			//psprite.addChild(pstatusBox);
			_rootStage.addChild(pstatusBox);
			
			plabel.move(0, 2);
			
			_lastPlayerY = _lastPlayerY + Math.round(_DefaultHeight/(GLOBALS.MAX_NUM_PLAYERS+1));
						
			psprite.addEventListener(MouseEvent.MOUSE_OVER, PlayerMouseOverHandler);
			psprite.addEventListener(MouseEvent.MOUSE_OUT, PlayerMouseOutHandler);
			
			addChild(psprite);
			draw();
			
			return new Array(plabel, pstatusBox);
			}
		protected function onStatusBoxComplete(e:Event):void
			{
			var pstatusBox:PlayerStatusBox = e.currentTarget as PlayerStatusBox;
			pstatusBox.x = this.width;
			}
		protected function add_empty_viewer(num:int):void
			{
			var plabel:Label = new Label();
			var labelStr:String = "#" + String(num) + ":" + _myStrings.StatusEmptySlot;
			plabel.autoSize = TextFieldAutoSize.LEFT;
			
			plabel.text = labelStr;
			
			/* create a wrapping sprite object */
			
			var psprite:Sprite = new Sprite();
			
			with (psprite)
				{
				x		= 1;
				y		= _lastPlayerY + 2;
				
				if (GLOBALS.DEBUG & GLOBALS.DEBUG_VIEW)
					trace("[PlayerStatusView] [psprite] x = " + psprite.x + ", y = " + psprite.y);
			
				with (graphics) 
					{
					lineStyle(1, GLOBALS.SEROUND_COLOR, 1, false, "normal", null);
					beginFill(INACTIVE_COLOR, 0.7);
		         	drawRoundRect(0, 0, _DefaultWidth - 1, Math.round(_DefaultHeight / (GLOBALS.MAX_NUM_PLAYERS+1)), 5, 5);
					endFill();
					}
				blendMode = BlendMode.LAYER;
			
				addChild(plabel);
				}
				
			plabel.move(0, 2);
			_lastPlayerY = _lastPlayerY + Math.round(_DefaultHeight/(GLOBALS.MAX_NUM_PLAYERS+1));
			
			addChild(psprite);
			draw();
			}
				
		protected function onAddPlayer(e:Event):void
			{
			addPlayers();
			}
		protected function onRemovedPlayer(e:Event):void
			{
			removePlayerRow(_players.lastHandeledPlayer);
			}
		
		protected function onCashUpdate(e:Event):void
			{
			var player:Player = e.currentTarget as Player;
			
			var labelStr:String = _myStrings.StatusCCash(player.Name, player.Cash);
			_playersLabelMap [ player ][0].text = labelStr;
			draw();
			}
			
		protected function draw():void
			{
			for (var key:Object in _playersLabelMap)
				{
				_playersLabelMap [ key ][0].drawNow();
				}
			}
		protected function PlayerMouseOverHandler(event:MouseEvent):void
			{
			var psprite:Sprite = event.currentTarget as Sprite;
			
			for (var key:Object in _playersLabelMap)
				{
				 if (_playersLabelMap [ key ][0].parent == psprite && event.relatedObject != _playersLabelMap [ key ][1])
					{
					//_rootStage.setChildIndex(_playersLabelMap [ key ][1], _rootStage.numChildren-1);
					this.setChildIndex(psprite,this.numChildren-1);
			        _playersLabelMap [ key ][1].draw_statusBox();
					break;
					}
				}
			}
		protected function PlayerMouseOutHandler(event:MouseEvent):void
			{
			var psprite:Sprite = event.target as Sprite;
			
			for (var key:Object in _playersLabelMap)
				{
				/* KISS !! */
				_playersLabelMap [ key ][1].undraw_statusBox();
				}
    		}
		}
}